package pe.edu.upc.jtigers.svpn.data.common;

import java.lang.reflect.Field;
import java.util.Collection;
import java.util.Set;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.Parameter;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

public abstract class BaseDao<T extends Object> {

	@PersistenceContext
	protected EntityManager entityManager;

	public Query createSimpleQuery(String queryString, Object entity)
			throws NoSuchFieldException, SecurityException,
			IllegalArgumentException, IllegalAccessException {

		Query q = entityManager.createQuery(queryString);

		if (entity != null) {
			Set<Parameter<?>> parameters = q.getParameters();

			for (Parameter<?> parameter : parameters) {
				String[] fieldsArray = parameter.getName().split("_");

				Object field = entity;
				for (int i = 0; i < fieldsArray.length; i++) {

					field = getValueParameter(fieldsArray[i], field);
					System.out.println("find parameter value -> "
							+ fieldsArray[i] + " : " + field);
				}
				q.setParameter(parameter.getName(), field);
			}

		}

		return q;
	}

	public Query createSimpleQuery(String queryString)
			throws NoSuchFieldException, SecurityException,
			IllegalArgumentException, IllegalAccessException {
		return createSimpleQuery(queryString, null);
	}

	private Object getValueParameter(String fieldName, Object entity)
			throws NoSuchFieldException, SecurityException,
			IllegalArgumentException, IllegalAccessException {

		Class<?> type = entity.getClass();
		Field field = type.getDeclaredField(fieldName);
		field.setAccessible(true);
		return field.get(entity);
	}

	@SuppressWarnings("unchecked")
	public Collection<T> getResultList(String queryString, Object entity)
			throws NoSuchFieldException, SecurityException,
			IllegalArgumentException, IllegalAccessException {
		Query q = createSimpleQuery(queryString, entity);
		return q.getResultList();
	}

	public Collection<T> getResultList(String queryString)
			throws NoSuchFieldException, SecurityException,
			IllegalArgumentException, IllegalAccessException {
		return getResultList(queryString, null);
	}

	@SuppressWarnings("unchecked")
	public T getSingleResult(String queryString, Object entity)
			throws NoSuchFieldException, SecurityException,
			IllegalArgumentException, IllegalAccessException {
		Query q = createSimpleQuery(queryString, entity);
		T result = null;
		try {
			result = (T) q.getSingleResult();
		} catch (NoResultException e) {
			result = null;
		}
		return result;
	}

	public T getSingleResult(String queryString) throws NoSuchFieldException,
			SecurityException, IllegalArgumentException, IllegalAccessException {
		return getSingleResult(queryString, null);
	}
}
